package com.robert.autoplayvideo;

import com.isotne.glidelibrary.utils.OhosGlide;
import ohos.agp.components.*;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.window.service.WindowManager;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.media.common.Source;
import ohos.media.player.Player;
import okhttp3.*;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

public class VideoItemProvider extends RecycleItemProvider {
    protected Context context;
    private ArrayList<VideoModel> videos = new ArrayList<>();
    private boolean downloadVideos = false;
    private File downloadPath;
    private Player player;
    public VideoItemProvider(Context context, ArrayList<VideoModel> videos) {
        this.context = context;
        this.videos=videos;
        player=new Player(context);
        downloadPath=context.getExternalFilesDir(Environment.DIRECTORY_MOVIES);
        if (!downloadPath.exists()) {
            downloadPath.mkdirs();
        }
        notifyDataChanged();
    }

    public void setDownloadVideos(boolean downloadVideos) {
        this.downloadVideos = downloadVideos;
    }
    public void setDownloadPath(File downloadPath) {
        if (!downloadPath.exists()) {
            downloadPath.mkdirs();
        }
        this.downloadPath = downloadPath;
    }


    @Override
    public int getCount() {
        return videos.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }
    @Override
    public Component getComponent(int postion, Component component, ComponentContainer componentContainer) {
        VideoModel model=videos.get(postion);
        Component view;
        view = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_view_videoitem_provider_item,null,false);
        Text name= (Text) view.findComponentById(ResourceTable.Id_video_or_image_name);
        Image image= (Image) view.findComponentById(ResourceTable.Id_image_view);
        Text state= (Text) view.findComponentById(ResourceTable.Id_video_state);
        Text vulume= (Text) view.findComponentById(ResourceTable.Id_video_vulume);
        DirectionalLayout surfaceProviderView= (DirectionalLayout) view.findComponentById(ResourceTable.Id_surfaceprovider_view);
        Slider slider= (Slider) view.findComponentById(ResourceTable.Id_video_slider);
        name.setText(model.getName()+"");
        if(model.getName().contains("Image")){
            surfaceProviderView.setVisibility(Component.HIDE);
            state.setVisibility(Component.HIDE);
            vulume.setVisibility(Component.HIDE);
        }else {
            surfaceProviderView.setVisibility(Component.VISIBLE);
            state.setVisibility(Component.VISIBLE);
            vulume.setVisibility(Component.VISIBLE);
            context.getUITaskDispatcher().asyncDispatch(new Runnable() {
                @Override
                public void run() {
                    if(postion==0){
                        state.setVisibility(Component.HIDE);
                        image.setVisibility(Component.HIDE);
                        initSurfaceToPlayer(postion,surfaceProviderView,state);
                    }
                }
            });
            state.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    //播放按钮隐藏
                    state.setVisibility(Component.HIDE);
                    image.setVisibility(Component.HIDE);
                    initSurfaceToPlayer(postion,surfaceProviderView,state);
                }
            });
            vulume.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    slider.setVisibility(Component.VISIBLE);
                    context.getUITaskDispatcher().delayDispatch(new Runnable() {
                        @Override
                        public void run() {
                            slider.setVisibility(Component.HIDE);
                        }
                    },5000L);
                }
            });
            slider.setValueChangedListener(new Slider.ValueChangedListener() {
                @Override
                public void onProgressUpdated(Slider slider, int i, boolean b) {
                    if(player!=null){
                        player.setVolume(i);
                    }
                }

                @Override
                public void onTouchStart(Slider slider) {

                }

                @Override
                public void onTouchEnd(Slider slider) {

                }
            });
        }
        context.getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                try {
                    OhosGlide.with(context)
                            .load(model.getImage_url())
                            .def(ResourceTable.Media_icon)
                            .into(image);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        return view;
    }
    private void initSurfaceToPlayer(int index,DirectionalLayout surfaceProviderView,Text videoState){
        if(surfaceProviderView.getChildCount()>0){
            surfaceProviderView.removeAllComponents();
        }
        VideoModel model=videos.get(index);
        DirectionalLayout.LayoutConfig layoutConfig=new DirectionalLayout.LayoutConfig(DirectionalLayout.LayoutConfig.MATCH_PARENT,DirectionalLayout.LayoutConfig.MATCH_PARENT);
        SurfaceProvider sfProvider=new SurfaceProvider(context);
        sfProvider.setLayoutConfig(layoutConfig);
        sfProvider.pinToZTop(false);
        WindowManager.getInstance().getTopWindow().get().setTransparent(true);
        surfaceProviderView.addComponent(sfProvider);
        //sfProvider添加监听事件
        sfProvider.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if(player.isNowPlaying()){
                    //如果正在播放，就暂停
                    player.pause();
                    //播放按钮可见
                    videoState.setVisibility(Component.VISIBLE);
                }else {
                    //如果暂停，点击继续播放
                    player.play();
                    //播放按钮隐藏
                    videoState.setVisibility(Component.HIDE);
                }
            }
        });
        sfProvider.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
            @Override
            public void surfaceCreated(SurfaceOps surfaceOps) {
                if (sfProvider.getSurfaceOps().isPresent()) {
                    Surface surface = sfProvider.getSurfaceOps().get().getSurface();
                    try {
                        Source source;
                        if(downloadVideos){
                            // 判断文件目录是否存在
                            File NowFile=new File(downloadPath,getFileName(model.getVideo_url()));
                            if (!NowFile.exists()) {
                                context.getUITaskDispatcher().asyncDispatch(new Runnable() {
                                    @Override
                                    public void run() {
                                        new ToastDialog(context).setContentText("正在下载...").show();
                                    }
                                });
                                context.getGlobalTaskDispatcher(TaskPriority.DEFAULT).asyncDispatch(new Runnable() {
                                    @Override
                                    public void run() {
                                        startDownloadInBackground(model.getVideo_url());
                                    }
                                });
                                source=new Source(model.getVideo_url());
                            }else {
                                FileInputStream in = new FileInputStream(NowFile);
                                FileDescriptor filedesc = in.getFD();
                                source=new Source(filedesc);
                            }
                        }else {
                            source=new Source(model.getVideo_url());
                        }
                        player.setSource(source);
                        player.setVideoSurface(surface);
                        player.prepare();
                        sfProvider.setTop(0);
                        player.play();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {

            }

            @Override
            public void surfaceDestroyed(SurfaceOps surfaceOps) {

            }
        });
    }
    public static final int DOWNLOAD_CHUNK_SIZE = 2048; //Same as Okio Segment.SIZE
    private void startDownloadInBackground(String url){
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(10, TimeUnit.SECONDS);
        builder.readTimeout(60, TimeUnit.SECONDS);
        builder.writeTimeout(60, TimeUnit.SECONDS);
        builder.retryOnConnectionFailure(false);
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[] { new MyTrustManager() },new SecureRandom());
            builder.sslSocketFactory(sc.getSocketFactory(),new MyTrustManager() );
            builder.hostnameVerifier(new MyHostnameVerifier());
        } catch (Exception e) {
            e.printStackTrace();
        }

        OkHttpClient client =builder.build();
        File tmpFile = new File(downloadPath,getFileName(url));
        try {
            Request request = new Request.Builder()
                    .url(url)
                    .build();
            File finalTmpFile = tmpFile;
            File finalTmpFile1 = tmpFile;
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    e.printStackTrace();
                    System.out.println("错误");
                    if (finalTmpFile1 != null) finalTmpFile1.delete();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    ResponseBody body = response.body();
//                    long contentLength =  body.contentLength();
                    HttpUrl realUrl = response.request().url();
                    String fileName="";
                    if (realUrl != null) {
                        String temp = realUrl.toString();
                        fileName = temp.substring(temp.lastIndexOf("/") + 1);

                    }
                    System.out.println("--------------fileName"+fileName);

                    long totalRead = 0;
                    long read;
                    BufferedSource source = body.source();
                    BufferedSink sink = Okio.buffer(Okio.sink(finalTmpFile));
                    while ((read = source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) {
                        totalRead += read;
                    }
                    sink.writeAll(source);
                    sink.flush();
                    sink.close();
                    body.close();
                    response.close();
                }
            });

        } catch (Exception e) {
            if (tmpFile != null) tmpFile.delete();
        }
    }
    public String getFileName(String urlname) {
        int start = urlname.lastIndexOf("/");
        int end = urlname.length();
        if (start != -1 && end != -1) {
            return urlname.substring(start+1,end);
        } else {
            return null;
        }
    }
}
